﻿/**************************************************************
 *
 * 唯一标识：23d7abe5-f26d-4e5d-862c-5581824b195c
 * 命名空间：Sgr.Indentity.Controllers
 * 创建时间：2023/8/21 11:34:49
 * 机器名称：DESKTOP-S0D075D
 * 创建者：antho
 * 电子邮箱：fengqinhua2016@163.com
 * 描述：
 *
 **************************************************************/

using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using Sgr.Indentity.Application.Commands;
using Sgr.Indentity.Application.ViewModels;

namespace Sgr.Indentity.Controllers
{
    /// <summary>
    /// JWT认证服务接口
    /// </summary>
    [Route("api/v1/sgr/oauth")]
    [ApiController]
    [AllowAnonymous]
    [Produces("application/json")]
    [Tags("OAuth")]
    public class OAuthController : ControllerBase
    {
        private readonly IMediator _mediator;

        /// <summary>
        /// 初始化认证服务控制器
        /// </summary>
        /// <param name="mediator">中介者服务</param>
        public OAuthController(IMediator mediator)
        {
            _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
        }

        /// <summary>
        /// 用户登录获取JWT令牌
        /// </summary>
        /// <param name="command">登录信息</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/oauth/token
        ///     {
        ///         "name": "admin",
        ///         "password": "password123",
        ///         "timestamp": "2025-04-02T10:00:00Z",
        ///         "nonce": "random_string",
        ///         "signature": "calculated_signature",
        ///         "verificationCode": "1234",
        ///         "verificationHash": "hash_value"
        ///     }
        /// </remarks>
        /// <response code="200">登录成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="429">请求过于频繁</response>
        [HttpPost("token")]
        [EnableRateLimiting("RateLimiterPolicy.Sgr.Identity.Login")]
        [ProducesResponseType(typeof(TokenViewModel), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status429TooManyRequests)]
        public async Task<ActionResult<TokenViewModel>> TokenAsync([FromBody] UserLoginCommand command, CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return !result.IsSuccess || result.Data == null
                ? this.CustomBadRequest(result.Message)
                : Ok(result.Data);
        }

        /// <summary>
        /// 使用验证码登录获取JWT令牌
        /// </summary>
        /// <param name="command">验证码登录信息</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/oauth/verify-code-token
        ///     {
        ///         "receiverType": "Email",
        ///         "purpose": "Login",
        ///         "receiver": "user@example.com",
        ///         "verificationCode": "123456",
        ///         "imageVerificationCode": "abcd",
        ///         "imageVerificationHash": "hash_value",
        ///         "timestamp": "2025-04-02T10:00:00Z",
        ///         "nonce": "random_string",
        ///         "signature": "calculated_signature"
        ///     }
        /// </remarks>
        /// <response code="200">登录成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="429">请求过于频繁</response>
        [HttpPost("verify-code-token")]
        [EnableRateLimiting("RateLimiterPolicy.Sgr.Identity.Login")]
        [ProducesResponseType(typeof(TokenViewModel), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status429TooManyRequests)]
        public async Task<ActionResult<TokenViewModel>> VerifyCodeTokenAsync([FromBody] VerifyCodeLoginCommand command, CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return !result.IsSuccess || result.Data == null
                ? this.CustomBadRequest(result.Message)
                : Ok(result.Data);
        }

        /// <summary>
        /// 刷新JWT令牌
        /// </summary>
        /// <param name="command">刷新令牌请求信息</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/oauth/refresh-token
        ///     {
        ///         "accessToken": "expired_token",
        ///         "timestamp": "2025-04-02T10:00:00Z",
        ///         "nonce": "random_string",
        ///         "signature": "calculated_signature"
        ///     }
        /// </remarks>
        /// <response code="200">刷新成功</response>
        /// <response code="400">请求参数验证失败或令牌无效</response>
        /// <response code="429">请求过于频繁</response>
        [HttpPost("session/refresh-token")]
        [EnableRateLimiting("RateLimiterPolicy.Sgr.Identity")]
        [ProducesResponseType(typeof(TokenViewModel), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status429TooManyRequests)]
        public async Task<ActionResult<TokenViewModel>> RefreshTokenAsync([FromBody] RefreshTokenCommand command, CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return !result.IsSuccess || result.Data == null
                ? this.CustomBadRequest(result.Message)
                : Ok(result.Data);
        }

        /// <summary>
        /// 注销当前用户
        /// </summary>
        /// <param name="command">注销请求信息</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/oauth/logout
        ///     {
        ///         "accessToken": "current_token",
        ///         "timestamp": "2025-04-02T10:00:00Z",
        ///         "nonce": "random_string",
        ///         "signature": "calculated_signature"
        ///     }
        /// </remarks>
        /// <response code="200">注销成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="429">请求过于频繁</response>
        [HttpPost("session/logout")]
        [EnableRateLimiting("RateLimiterPolicy.Sgr.Identity")]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status429TooManyRequests)]
        public async Task<ActionResult<bool>> LogoutAsync([FromBody] LogoutCommand command, CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return !result.IsSuccess
                ? this.CustomBadRequest(result.Message)
                : Ok(result.Data);
        }
    }
}